import sys, time, os
from PyQt5.QtWidgets import QMainWindow, QApplication, QFileDialog, QMessageBox
from pyqt5_plugins.examplebuttonplugin import QtGui
import numpy as np
import uiTools.saveAsExl, uiTools.feature, uiTools.show

import ui
import detect

# 全局窗口app
app = QApplication(sys.argv)


class MyWindows(ui.Ui_MainWindow, QMainWindow):
    def __init__(self):
        super(MyWindows, self).__init__()
        # 初始化UI
        self.setupUi(self)
        # 初始绑定各个按钮的功能
        self.handle_buttons()
        # tips信息
        self.selectedFile.setText('暂无,请点击左侧按钮选择路径')
        self.selectedSavePath.setText('暂无,请点击左侧按钮选择路径')
        # 检测类型 0为默认  单张检测为1  文件夹多张检测为2
        self.detectType = 0
        # 当选择检测一个文件夹的时候，其中保存当前文件夹中所有以bmp,jpg,png结尾的文件名称
        self.picArray = []

    # 初始绑定各个按钮的功能
    def handle_buttons(self):
        # 选择待检测图片
        self.selectFile.clicked.connect(self.onSelectPicFile)
        # 选择待检测图片文件
        self.selectFileDir.clicked.connect(self.onSelectPicFileDir)
        # 选择结果保存路径
        self.selectSavePath.clicked.connect(self.onSelectSavePath)
        # 开始检测
        self.detect.clicked.connect(self.onDetectPic)

    # 选择待检测图片
    def onSelectPicFile(self):
        # 选择待检测的图片,展示在待检测区
        filename, filetype = QFileDialog.getOpenFileName(self, '请选择待检图片')
        self.singlePicPath = filename
        # 显示选择路径的指定图片
        jpg = QtGui.QPixmap(filename).scaled(self.imageShow.width(), self.imageShow.height())
        self.selectedFile.setText(filename)
        self.imageShow.setPixmap(jpg)
        # 调整检测类型为单张
        self.detectType = 1

    # 选择待检测图片文件
    def onSelectPicFileDir(self):
        # 选择文件夹路径
        self.selectedFile.setText(QFileDialog.getExistingDirectory(self, '请选择待检文件夹'))
        # 调整检测类型为文件夹多张
        self.detectType = 2
        # 选择文件夹时 仅展示文件夹中第一张图片
        self.picArray = []

        # 判断当前文件中是否存在以jpg、bmp、png为结尾的文件
        for root, dirs, files in os.walk(self.selectedFile.text()):
            for file in files:
                # 检测的目标个数
                ext = os.path.splitext(file)[-1].lower()
                # 用文件后缀名判断当前文件夹中是否有图片类型
                if ext == '.jpg' or ext == '.bmp' or ext == '.png':
                    self.picArray.append(file)

        # 当文件夹中图片的个数大于0的时候才会展示一张出来
        if len(self.picArray) > 0:
            self.DirFirstPicPath = self.selectedFile.text() + '/' + self.picArray[0]
            # 显示文件夹中的第一个图片
            jpg = QtGui.QPixmap(self.DirFirstPicPath).scaled(self.imageShow.width(), self.imageShow.height())
            self.imageShow.setPixmap(jpg)

        else:
            QMessageBox.information(self, '提示', '当前选择文件夹中不存在以jpg、bmp、png结尾的图片文件，请重新选择！', QMessageBox.Yes)
            self.selectedFile.setText('暂无,请点击左侧按钮选择路径')

    # 选择结果保存路径 是个文件夹就行
    def onSelectSavePath(self):
        self.selectedSavePath.setText(QFileDialog.getExistingDirectory())

    # 开始检测
    def onDetectPic(self):
        # 判断图片和保存路径是否选择 没选择就显示提示信息并不往下执行
        if self.selectedSavePath.text() == '暂无,请点击左侧按钮选择路径' and self.detectType == 1:
            QMessageBox.information(self, '提示', '请选择待检测图片路径!', QMessageBox.Yes)

        if self.selectedSavePath.text() == '暂无,请点击左侧按钮选择路径' and self.detectType == 2:
            QMessageBox.information(self, '提示', '请选择结果保存路径!', QMessageBox.Yes)

        # detectType为1时候，进行单张图片的检测
        elif self.selectedSavePath.text() != '暂无,请点击左侧按钮选择路径' and self.detectType == 1:
            # 图片保存文件夹设置为当前时间
            t = time.localtime()
            fileDirName = time.strftime("%Y-%m-%d-%H-%M-%S", t)
            # 在yolo的detect文件中重新创建了一个方法outSide,传入指定参数同样可以进行检测
            # 参数 source=待检测图片 savePath=结果保存路径 fileDirName=结果要保存在一个文件夹中
            detect.outSide(
                source=self.selectedFile.text(),
                savePath=self.selectedSavePath.text(),
                name=str(fileDirName)
            )

            # 通过检测结果保存的路径,在待检测区展示检测结果图
            picName = self.singlePicPath.split("/")
            picNameLast = picName[-1]
            showImagePath = str(self.selectedSavePath.text()) + '/' + str(fileDirName) + '/' + picNameLast
            jpg = QtGui.QPixmap(showImagePath).scaled(self.imageShowDetect.width(), self.imageShowDetect.height())
            self.imageShowDetect.setPixmap(jpg)

            # 统计检测出的目标个数
            countGranularSludge = 0
            countEpistylis = 0
            countFloc = 0
            countRotifer = 0
            countFilamentousbacteria = 0

            # 一张图中所有颗粒污泥的实际直径
            averageAd = []
            averageFd = []
            # 循环读取裁剪出来的目标个数,统计检测结果
            for root, dirs, files in os.walk(
                    self.selectedSavePath.text() + "/" + fileDirName + "./crops/Granular Sludge/"):
                countGranularSludge = len(files)
                for file in files:
                    # 此处进行单张图片的特征计算

                    # 分割后的绝对路径
                    absPath = self.selectedSavePath.text() + "/" + fileDirName + "./crops/Granular Sludge/" + file
                    # 读取图片特征计算

                    # 计算每张图的最大颗粒粒径
                    averageAd.append(uiTools.feature.featureCalculateAd(absPath))
                    # 计算颗粒污泥分形
                    averageFd.append(uiTools.feature.featureCalculateFd(absPath))

            for root, dirs, files in os.walk(self.selectedSavePath.text() + "/" + fileDirName + "./crops/Epistylis/"):
                countEpistylis = len(files)

            for root, dirs, files in os.walk(self.selectedSavePath.text() + "/" + fileDirName + "./crops/Rotifer/"):
                countRotifer = len(files)

            for root, dirs, files in os.walk(self.selectedSavePath.text() + "/" + fileDirName + "./crops/Floc/"):
                countFloc = len(files)

            for root, dirs, files in os.walk(
                    self.selectedSavePath.text() + "/" + fileDirName + "./crops/Filamentous bacteria/"):
                countFilamentousbacteria = len(files)

            # 拼接保存路径
            excelPath = str(self.selectedSavePath.text()) + '/' + str(fileDirName)

            # 把目标个数统计结果保存至excel
            uiTools.saveAsExl.saveDetectAsExl(excelPath,
                                              countGranularSludge,
                                              countEpistylis,
                                              countFloc,
                                              countRotifer,
                                              countFilamentousbacteria,
                                              )

            # 把颗粒污泥等效直径保存至excel
            uiTools.saveAsExl.saveRealAdAsExl(excelPath, averageAd, averageFd)

            # 计算所以颗粒污泥的平均粒径
            totleavead = 0
            for ele in range(0, len(averageAd)):
                totleavead = totleavead + averageAd[ele]

            totleavefd = 0
            for ele in range(0, len(averageFd)):
                totleavefd = totleavefd + averageFd[ele]
            # 展示检测结果
            self.statisticTitle.setText('检测结果统计如下:')
            self.statistic.setText('颗粒污泥个数:' + str(countGranularSludge) + '个\n' +
                                   '累枝虫个数:' + str(countEpistylis) + '个\n' +
                                   '轮虫个数:' + str(countRotifer) + '个\n' +
                                   '絮体个数:' + str(countFloc) + '个\n' +
                                   '丝状菌个数:' + str(countFilamentousbacteria) + '个\n\n' +
                                   '颗粒污泥平均粒径:' + str(round(totleavead / countGranularSludge, 2)) + ' um\n' +
                                   '颗粒污泥平均分形:' + str(round(totleavefd / countGranularSludge, 4)) + '\n' +
                                   '颗粒污泥粒径标准差:' + str(round(np.std(averageAd), 3)) + ' \n' +
                                   '颗粒污泥分形标准差:' + str(round(np.std(averageFd), 3)) + ' \n')

            # 图表保存路径
            figurePath = excelPath + './' + fileDirName
            uiTools.show.savePic(averageAd, figurePath)
            # # 粒径分布图展示
            figPath = str(self.selectedSavePath.text()) + '/' + str(fileDirName) + '/' + fileDirName + '.png'
            StatisticJpg = QtGui.QPixmap(figPath).scaled(self.imageShowStatis.width(), self.imageShowStatis.height())
            self.imageShowStatis.setPixmap(StatisticJpg)

        # detectType为2时候，进行一个文件夹中所有图片的检测
        elif self.selectedSavePath.text() != '暂无,请点击左侧按钮选择路径' and self.detectType == 2:
            # 图片保存文件夹设置为当前时间
            t = time.localtime()
            fileDirName = time.strftime("%Y-%m-%d-%H-%M-%S", t)
            # 在yolo的detect文件中重新创建了一个方法outSide,传入指定参数同样可以进行检测
            # 参数 source=待检测图片 savePath=结果保存路径 fileDirName=结果要保存在一个文件夹中
            detect.outSide(
                source=self.selectedFile.text(),
                savePath=self.selectedSavePath.text(),
                name=str(fileDirName)
            )

            # 只展示出待检测文件中第一张图片的检测结果，展示在界面上
            showImagePath = str(self.selectedSavePath.text()) + '/' + str(fileDirName) + '/' + self.picArray[0]
            jpg = QtGui.QPixmap(showImagePath).scaled(self.imageShowDetect.width(), self.imageShowDetect.height())
            self.imageShowDetect.setPixmap(jpg)

            # 统计文件夹中所有图片检测出的目标个数
            countGranularSludge = 0
            countEpistylis = 0
            countFloc = 0
            countRotifer = 0
            countFilamentousbacteria = 0

            averageAd = []
            averageFd = []
            detectedPicCount = 0
            for root, dirs, files in os.walk(self.selectedFile.text()):
                detectedPicCount = len(files)
                # print('一共有',detectedPicCount,'张图片被检测')
            for root, dirs, files in os.walk(
                    self.selectedSavePath.text() + "/" + fileDirName + "./crops/Granular Sludge/"):
                countGranularSludge = len(files)
                for file in files:
                    # 此处进行单张图片的特征计算

                    # 分割后的绝对路径
                    absPath = self.selectedSavePath.text() + "/" + fileDirName + "./crops/Granular Sludge/" + file
                    # 读取图片特征计算

                    # 计算每张图的最大颗粒粒径
                    averageAd.append(uiTools.feature.featureCalculateAd(absPath))
                    # 计算颗粒污泥分形
                    averageFd.append(uiTools.feature.featureCalculateFd(absPath))

            for root, dirs, files in os.walk(self.selectedSavePath.text() + "/" + fileDirName + "./crops/Epistylis/"):
                countEpistylis = len(files)

            for root, dirs, files in os.walk(self.selectedSavePath.text() + "/" + fileDirName + "./crops/Rotifer/"):
                countRotifer = len(files)

            for root, dirs, files in os.walk(self.selectedSavePath.text() + "/" + fileDirName + "./crops/Floc/"):
                countFloc = len(files)

            for root, dirs, files in os.walk(
                    self.selectedSavePath.text() + "/" + fileDirName + "./crops/Filamentous bacteria/"):
                countFilamentousbacteria = len(files)

            # 拼接保存路径
            excelPath = str(self.selectedSavePath.text()) + '/' + str(fileDirName)

            # 把目标个数统计结果保存至excel
            uiTools.saveAsExl.saveDetectAsExl(excelPath,
                                              countGranularSludge,
                                              countEpistylis,
                                              countFloc,
                                              countRotifer,
                                              countFilamentousbacteria,
                                              )

            # 把颗粒污泥等效直径保存至excel
            uiTools.saveAsExl.saveRealAdAsExl(excelPath, averageAd, averageFd)

            # 计算所以颗粒污泥的平均粒径
            totleavead = 0
            for ele in range(0, len(averageAd)):
                totleavead = totleavead + averageAd[ele]

            totleavefd = 0
            for ele in range(0, len(averageFd)):
                totleavefd = totleavefd + averageFd[ele]
            # 展示检测结果
            self.statisticTitle.setText('检测结果统计如下:')
            self.statistic.setText('全部颗粒污泥个数:' + str(countGranularSludge) + '个\n' +
                                   '全部累枝虫个数:' + str(countEpistylis) + '个\n' +
                                   '全部轮虫个数:' + str(countRotifer) + '个\n' +
                                   '全部絮体个数:' + str(countFloc) + '个\n' +
                                   '全部丝状菌个数:' + str(countFilamentousbacteria) + '个\n\n' +
                                   '平均颗粒污泥个数:' + str(countGranularSludge/detectedPicCount) + '个\n' +
                                   '平均累枝虫个数:' + str(countEpistylis/detectedPicCount) + '个\n' +
                                   '平均轮虫个数:' + str(countRotifer/detectedPicCount) + '个\n' +
                                   '平均絮体个数:' + str(countFloc/detectedPicCount) + '个\n' +
                                   '平均丝状菌个数:' + str(countFilamentousbacteria/detectedPicCount) + '个\n\n' +
                                   '颗粒污泥平均粒径:' + str(round(totleavead / countGranularSludge, 2)) + ' um\n' +
                                   '颗粒污泥平均分形:' + str(round(totleavefd / countGranularSludge, 4)) + '\n' +
                                   '颗粒污泥粒径标准差:' + str(round(np.std(averageAd), 3)) + ' \n' +
                                   '颗粒污泥分形标准差:' + str(round(np.std(averageFd), 3)) + ' \n')

            # 图表保存路径
            figurePath = excelPath + './' + fileDirName
            uiTools.show.savePic(averageAd, figurePath)
            # 粒径分布图展示
            figPath = str(self.selectedSavePath.text()) + '/' + str(fileDirName) + '/' + fileDirName + '.png'
            StatisticJpg = QtGui.QPixmap(figPath).scaled(self.imageShowStatis.width(), self.imageShowStatis.height())
            self.imageShowStatis.setPixmap(StatisticJpg)


my_windows = MyWindows()  # 实例化对象
my_windows.show()  # 显示窗口

sys.exit(app.exec_())
